package com.rc.saas.tenant.service.acct;

import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.rc.saas.tenant.mapper.acct.AcctWithdrawApplyMapper;
import com.rc.saas.tenant.mapper.acct.AcctWithdrawOrderMapper;
import com.rc.saas.tenant.mapper.acct.TenantOperatorAccountMapper;
import com.rc.saas.tenant.mapper.acct.TenantOperatorAccountRecordMapper;
import com.rc.saas.tenant.mapper.member.MemberAccountMapper;
import com.rc.saas.tenant.mapper.member.MemberAccountRecordMapper;
import com.rc.saas.tenant.mapper.member.RcMemberFlagMapper;
import com.rc.saas.tenant.mapper.member.RcMemberGainSettingMapper;
import com.rc.saas.tenant.mapper.transfer.MemberRefundApplyMapper;
import com.rc.saas.tenant.model.acct.*;
import com.rc.saas.tenant.model.member.*;
import com.rc.saas.tenant.model.recharge.RechargeOrder;
import com.rc.saas.tenant.model.recharge.RechargeOrderExample;
import com.rc.saas.tenant.model.transfer.*;
import com.rc.saas.tenant.service.transfer.MemberRefundApplyService;
import com.rc.saas.tenant.service.transfer.TenantTransferService;
import com.rc.saas.tenant.vo.acct.AcctWithdrawOrderVo;
import com.rc.saas.tenant.vo.member.MemberRechargeVo;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by Sven on 2021/01/29
 */
@Service
public class AcctWithdrawOrderServiceImpl implements AcctWithdrawOrderService {
    private static Logger logger = LogManager.getLogger(AcctWithdrawOrderServiceImpl.class);

    @Autowired
    private AcctWithdrawOrderMapper acctWithdrawOrderMapper;

    @Autowired
    private TenantOperatorAccountMapper tenantOperatorAccountMapper;

    @Autowired
    private TenantOperatorAccountRecordMapper tenantOperatorAccountRecordMapper;

    @Autowired
    private AcctWithdrawApplyMapper acctWithdrawApplyMapper;

    @Autowired
    private MemberRefundApplyMapper memberRefundApplyMapper;

    @Autowired
    private MemberAccountMapper memberAccountMapper;

    @Autowired
    private RcMemberFlagMapper rcMemberFlagMapper;

    @Autowired
    private TenantTransferService tenantTransferService;

    @Autowired
    private MemberAccountRecordMapper memberAccountRecordMapper;

    @Autowired
    private RcMemberGainSettingMapper memberGainSettingMapper;

    @Override
    public AcctWithdrawOrderMapper getMapper() {
        return acctWithdrawOrderMapper;
    }

    @Override
    public void insertSelectiveReturnId(AcctWithdrawOrder acctWithdrawOrder) {
        acctWithdrawOrderMapper.insertSelectiveReturnId(acctWithdrawOrder);
    }

    @Override
    public synchronized void updateSuccessAcctWithdrawOrder(AlipayFundTransUniTransferResponse transferResponse, Long withdrawOrderId) {
        AcctWithdrawOrder acctWithdrawOrder = acctWithdrawOrderMapper.selectByPrimaryKey(withdrawOrderId);

        //到帐状态 0未到帐  1已到帐 2转账失败 默认0
        if (null != acctWithdrawOrder && !("1".equals(acctWithdrawOrder.getStatus()))) {
            Date date = new Date();

            //1 更新付款单状态
            AcctWithdrawOrder updateAcctWithdrawOrder = new AcctWithdrawOrder();
            updateAcctWithdrawOrder.setWithdrawOrderId(withdrawOrderId);
            updateAcctWithdrawOrder.setTransactionId(transferResponse.getOrderId());
            updateAcctWithdrawOrder.setFundTransactionId(transferResponse.getPayFundOrderId());

            updateAcctWithdrawOrder.setTransferTime(transferResponse.getTransDate());
            updateAcctWithdrawOrder.setStatus("1");
            updateAcctWithdrawOrder.setLastUpdatedTime(date);
            acctWithdrawOrderMapper.updateByPrimaryKeySelective(updateAcctWithdrawOrder);

            //2 更新分销商余额tenant_operator_account
            TenantOperatorAccount tenantOperatorAccount = tenantOperatorAccountMapper.selectByPrimaryKey(acctWithdrawOrder.getTenantOperatorCode());
            if (tenantOperatorAccount == null) {
                logger.error("找不到分销商余额记录:{}", acctWithdrawOrder.getTenantOperatorCode());
                throw new RuntimeException("找不到分销商余额记录");
            }

            //先更新余额，然后最新余额存储在AcctWithdrawOrderVo.account返回
            AcctWithdrawOrderVo acctWithdrawOrderVo = new AcctWithdrawOrderVo();
            acctWithdrawOrderVo.setTenantCode(acctWithdrawOrder.getTenantCode());
            acctWithdrawOrderVo.setTenantOperatorCode(acctWithdrawOrder.getTenantOperatorCode());
            acctWithdrawOrderVo.setAmount(acctWithdrawOrder.getAmount());
            tenantOperatorAccountMapper.updateTenantOperatorAccountByOperatorCode(acctWithdrawOrderVo);

            //3 分销商余额变动记录 tenant_operator_account_record
            TenantOperatorAccountRecord operatorAccountRecord = new TenantOperatorAccountRecord();
            operatorAccountRecord.setTenantCode(acctWithdrawOrder.getTenantCode());
            operatorAccountRecord.setTenantOperatorCode(acctWithdrawOrder.getTenantOperatorCode());
            operatorAccountRecord.setOutTradeNo(acctWithdrawOrder.getOutTradeNo());
            operatorAccountRecord.setTransactionId(transferResponse.getOrderId());
            operatorAccountRecord.setFundTransactionId(transferResponse.getPayFundOrderId());
            operatorAccountRecord.setWithdrawOrderId(acctWithdrawOrder.getWithdrawOrderId());

            //收款账户类型,0 对公（在金融机构开设的公司账户）,如果银行卡为对公，必须传递省市支行信息或者联行号 1对私（在金融机构开设的个人账户）
            operatorAccountRecord.setAccountType(acctWithdrawOrder.getAccountType());

            //记录类型(0 收入 1 提现)
            operatorAccountRecord.setRecordType("1");

            //本次变更金额
            operatorAccountRecord.setAmount(acctWithdrawOrder.getAmount());

            //更新后的acctWithdrawOrderVo.account
            operatorAccountRecord.setResult(acctWithdrawOrderVo.getAccount());

            operatorAccountRecord.setRemark("后台结算款提现");
            operatorAccountRecord.setCreatedTime(date);
            operatorAccountRecord.setLastUpdatedTime(date);
            tenantOperatorAccountRecordMapper.insertSelective(operatorAccountRecord);

            //4 更新申请单
            AcctWithdrawApply acctWithdrawApply = acctWithdrawApplyMapper.selectByPrimaryKey(acctWithdrawOrder.getWithdrawApplyId());
            if (acctWithdrawApply == null) {
                logger.error("AcctWithdrawApply 不存在申请记录:{}", acctWithdrawOrder.getWithdrawApplyId());
            }

            //审核状态 0待审核，1已处理，2驳回 3提现中 4已到账 5提现失败 默认0
            acctWithdrawApply.setStatus("4");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            acctWithdrawApply.setTransferTime(formatter.format(date));
            acctWithdrawApplyMapper.updateByPrimaryKeySelective(acctWithdrawApply);

            logger.info(acctWithdrawOrder.getTenantCode() + "-" + acctWithdrawOrder.getTenantOperatorCode() + ":后台结算款提现入账成功 outTradeNo:{},提现金额,:{},新的余额,:{}",
                    acctWithdrawOrder.getOutTradeNo(), acctWithdrawOrder.getAmount(), acctWithdrawOrderVo.getAccount());
        }
    }

    @Override
    public void updateSuccessByTransfer(AlipayFundTransUniTransferResponse transferResponse, Long withdrawOrderId, Long memberRefundApplyId) {
        AcctWithdrawOrder acctWithdrawOrder = acctWithdrawOrderMapper.selectByPrimaryKey(withdrawOrderId);

        //到帐状态 0未到帐  1已到帐 2转账失败 默认0
        if (null != acctWithdrawOrder && !("1".equals(acctWithdrawOrder.getStatus()))) {
            Date date = new Date();

            //1 更新付款单状态
            AcctWithdrawOrder updateAcctWithdrawOrder = new AcctWithdrawOrder();
            updateAcctWithdrawOrder.setWithdrawOrderId(withdrawOrderId);
            updateAcctWithdrawOrder.setTransactionId(transferResponse.getOrderId());
            updateAcctWithdrawOrder.setFundTransactionId(transferResponse.getPayFundOrderId());

            updateAcctWithdrawOrder.setTransferTime(transferResponse.getTransDate());
            updateAcctWithdrawOrder.setStatus("1");
            updateAcctWithdrawOrder.setLastUpdatedTime(date);
            acctWithdrawOrderMapper.updateByPrimaryKeySelective(updateAcctWithdrawOrder);


            MemberRefundApply memberRefundApply = memberRefundApplyMapper.selectByPrimaryKey(memberRefundApplyId);
            if (memberRefundApply == null) {
                logger.error("memberRefundApply 提现记录不存在:{}", memberRefundApply.getRefundApplyId());
            }

            //审核状态 0待审核，1已处理，2驳回 3提现中 4已到账 5提现失败 默认0
            memberRefundApply.setStatus("4");
            memberRefundApply.setLastUpdatedTime(new Date());
            memberRefundApply.setAuditingTime(new Date());
            memberRefundApply.setFaceAmount(memberRefundApply.getFaceAmount());
//            memberRefundApply.setOutTradeNo(acctWithdrawOrder.getOutTradeNo());  //订单号关联
            memberRefundApplyMapper.updateByPrimaryKeySelective(memberRefundApply);

            ////更新用户提现金额
            MemberAccount memberAccount = memberAccountMapper.selectByPrimaryKey(memberRefundApply.getMemberId());
//            //收益金总金额
//            memberAccount.setAllIncomeAmount(memberAccount.getAllTransferAmount().add(memberRefundApply.getFaceAmount()));
            //已提现总金额
            memberAccount.setAllTransferAmount(memberAccount.getAllTransferAmount().add(memberRefundApply.getFaceAmount()));
            //memberAccount.setIncomeAmount(memberAccount.getIncomeAmount().subtract(memberRefundApply.getRefundAmount()));


            MemberRefundApplyExample example = new MemberRefundApplyExample();
            example.createCriteria().andStatusEqualTo("4").andMemberIdEqualTo(memberRefundApply.getMemberId());
            long count = memberRefundApplyMapper.selectByExample(example).stream().count();
            TenantTransfer tenantTransfer = tenantTransferService.selectByExample(new TenantTransferExample()).stream().findFirst().orElseGet(() -> null);

            RcMemberFlag rcMemberFlag = rcMemberFlagMapper.selectByPrimaryKey(memberAccount.getMemberId());
            //超过次数无折扣
            if (tenantTransfer.getTransferNoRebate() <= count) {
                rcMemberFlag.setGiveStatus("1");
            }
            //超过次数无权益金
            if (tenantTransfer.getTransferNoMoney() <= count) {
                rcMemberFlag.setRechargeStatus("1");
            }

            //每次提现权益金与折扣都归0
            memberAccount.setGiveAccount(BigDecimal.ZERO);
            memberAccount.setFrozenGiveAccount(BigDecimal.ZERO);
            rcMemberFlag.setMemberLevel("V0");
            rcMemberFlag.setSubLevel("V0-1");

            rcMemberFlagMapper.updateByPrimaryKeySelective(rcMemberFlag);
            memberAccountMapper.updateByPrimaryKeySelective(memberAccount);

            logger.info("后台结算款提现入账成功 outTradeNo:{},提现金额,:{}",
                    acctWithdrawOrder.getOutTradeNo(), acctWithdrawOrder.getAmount());
        }
    }

    @Override
    public AcctWithdrawOrder selectAcctWithdrawOrderByOutTradeNo(String outTradeNo) {
        AcctWithdrawOrderExample example = new AcctWithdrawOrderExample();
        example.createCriteria().andOutTradeNoEqualTo(outTradeNo);
        return acctWithdrawOrderMapper.selectByExample(example).stream().findFirst().orElseGet(() -> null);
    }

    @Override
    public synchronized void updateSuccessAcctWithdrawOrder1(Long withdrawOrderId) {
        AcctWithdrawOrder acctWithdrawOrder = acctWithdrawOrderMapper.selectByPrimaryKey(withdrawOrderId);

        //到帐状态 0未到帐  1已到帐 2转账失败 默认0
        if (null != acctWithdrawOrder && !("1".equals(acctWithdrawOrder.getStatus()))) {
            Date date = new Date();

            //1 更新付款单状态
            AcctWithdrawOrder updateAcctWithdrawOrder = new AcctWithdrawOrder();
            updateAcctWithdrawOrder.setWithdrawOrderId(withdrawOrderId);
//            updateAcctWithdrawOrder.setTransactionId(transferResponse.getOrderId());
//            updateAcctWithdrawOrder.setFundTransactionId(transferResponse.getPayFundOrderId());
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            updateAcctWithdrawOrder.setTransferTime(format.format(new Date()));
            updateAcctWithdrawOrder.setStatus("1");
            updateAcctWithdrawOrder.setLastUpdatedTime(date);
            acctWithdrawOrderMapper.updateByPrimaryKeySelective(updateAcctWithdrawOrder);

            //2 更新分销商余额tenant_operator_account
            TenantOperatorAccount tenantOperatorAccount = tenantOperatorAccountMapper.selectByPrimaryKey(acctWithdrawOrder.getTenantOperatorCode());
            if (tenantOperatorAccount == null) {
                logger.error("找不到分销商余额记录:{}", acctWithdrawOrder.getTenantOperatorCode());
                throw new RuntimeException("找不到分销商余额记录");
            }

            //先更新余额，然后最新余额存储在AcctWithdrawOrderVo.account返回
            AcctWithdrawOrderVo acctWithdrawOrderVo = new AcctWithdrawOrderVo();
            acctWithdrawOrderVo.setTenantCode(acctWithdrawOrder.getTenantCode());
            acctWithdrawOrderVo.setTenantOperatorCode(acctWithdrawOrder.getTenantOperatorCode());
            acctWithdrawOrderVo.setAmount(acctWithdrawOrder.getAmount());
            tenantOperatorAccountMapper.updateTenantOperatorAccountByOperatorCode(acctWithdrawOrderVo);

            //3 分销商余额变动记录 tenant_operator_account_record
            TenantOperatorAccountRecord operatorAccountRecord = new TenantOperatorAccountRecord();
            operatorAccountRecord.setTenantCode(acctWithdrawOrder.getTenantCode());
            operatorAccountRecord.setTenantOperatorCode(acctWithdrawOrder.getTenantOperatorCode());
            operatorAccountRecord.setOutTradeNo(acctWithdrawOrder.getOutTradeNo());
//            operatorAccountRecord.setTransactionId(transferResponse.getOrderId());
//            operatorAccountRecord.setFundTransactionId(transferResponse.getPayFundOrderId());
            operatorAccountRecord.setWithdrawOrderId(acctWithdrawOrder.getWithdrawOrderId());

            //收款账户类型,0 对公（在金融机构开设的公司账户）,如果银行卡为对公，必须传递省市支行信息或者联行号 1对私（在金融机构开设的个人账户）
            operatorAccountRecord.setAccountType(acctWithdrawOrder.getAccountType());

            //记录类型(0 收入 1 提现)
            operatorAccountRecord.setRecordType("1");

            //本次变更金额
            operatorAccountRecord.setAmount(acctWithdrawOrder.getAmount());

            //更新后的acctWithdrawOrderVo.account
            operatorAccountRecord.setResult(acctWithdrawOrderVo.getAccount());

            operatorAccountRecord.setRemark("后台结算款提现");
            operatorAccountRecord.setCreatedTime(date);
            operatorAccountRecord.setLastUpdatedTime(date);
            tenantOperatorAccountRecordMapper.insertSelective(operatorAccountRecord);

            //4 更新申请单
            AcctWithdrawApply acctWithdrawApply = acctWithdrawApplyMapper.selectByPrimaryKey(acctWithdrawOrder.getWithdrawApplyId());
            if (acctWithdrawApply == null) {
                logger.error("AcctWithdrawApply 不存在申请记录:{}", acctWithdrawOrder.getWithdrawApplyId());
            }

            //审核状态 0待审核，1已处理，2驳回 3提现中 4已到账 5提现失败 默认0
            acctWithdrawApply.setStatus("4");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            acctWithdrawApply.setTransferTime(formatter.format(date));
            acctWithdrawApplyMapper.updateByPrimaryKeySelective(acctWithdrawApply);

            logger.info(acctWithdrawOrder.getTenantCode() + "-" + acctWithdrawOrder.getTenantOperatorCode() + ":后台结算款提现入账成功 outTradeNo:{},提现金额,:{},新的余额,:{}",
                    acctWithdrawOrder.getOutTradeNo(), acctWithdrawOrder.getAmount(), acctWithdrawOrderVo.getAccount());


        }
    }
}
